/************************************************
 * Copyright (c) 2007 ~ 2009, 
 * All rights reserved.
 * Version   : 1.0
 * Author    : lengsh@gmail.com 
 * Date      : 2009.1.2
 *************************************************/
#ifndef  __HOST_PARSER___H__
#define  __HOST_PARSER___H__

#include <string>
#include <iostream>
#include <stdlib.h>
#include <map>
#include <netdb.h>
#include <arpa/inet.h>
#include <sstream>
#include <string.h>
#include <map>
#include <vector>
using namespace std;

class HostParser {
	protected:
                map < string, int > m_hosts;
		bool CheckHosts()
		{
			return true;
		}
		int addString(const char *str)
		{
			string src = str;
			string::size_type idx = string::npos; 
			idx =  src.find('[', 0);
			if(idx == string::npos)
				return 0;
                    
                        string s1 = src.substr(0, idx);
                        string ss = src.substr(idx+1, src.length() - idx -1);
                        
                        string::size_type idx2 = ss.find(']', 0);
                        if(idx2 == string::npos)
                              return -1;

                        string s2 = ss.substr(idx2+1, ss.length() - idx2 -1);
                        ss = ss.substr(0, idx2);
                        string::size_type idx3 = ss.find('-', 0);
                        if(idx3 == string::npos)
                              return -1;
                        string sa = ss.substr(0, idx3);
                        ss = ss.substr(idx3+1, ss.length() - idx3 -1);    
			if(strcmp(sa.c_str(), ss.c_str()) >= 0)
				return  -1;
			/*                
					  for(int a = 0; a <(int) sa.length(); a++)
					  {
					  if(g_ascii_isalnum(sa.at(a)) != TRUE)
					  return -1;    
					  }

					  for(int a = 0; a <(int) ss.length(); a++)
					  {
					  if(g_ascii_isalnum(ss.at(a)) != TRUE)
					  return -1;    
					  }
					  */
                        int i = atoi(sa.c_str());
                        int j = atoi(ss.c_str());
                        int ic = j - i + 1;
                        for(; i <=j; i++)
                        {
                              char buf[20];
                              sprintf(buf,"%d", i);
                              ss = "";
                              ss.append(buf);
                              string h = s1;
                              h.append(ss);
                              h.append(s2);
                              m_hosts[h.c_str()] = 0; 
                        } 

			return ic;
		}

	public:
                int ParseHostString(string &str)
                {
                    return ParseHostString(str.c_str());
                }
		int ParseHostString(const char *str)
		{
			if(addString(str) == 0)
                        {
                              cout<< __func__<<" : "<< str <<endl; 
				m_hosts[str] = 0;
                        }
                        map < string, int > ::iterator iter;
                        while(true)
                       {
                           for(iter = m_hosts.begin(); iter != m_hosts.end(); iter++)
			   {
				   string ns = iter->first;  
				   int ret = addString( ns.c_str());
				   if(ret > 0 )
				   {

					   m_hosts.erase(ns.c_str());
					   break;
				   }
				   if(ret < 0)
					   return -1; 
			   }
			   if(iter == m_hosts.end())
				   break;
		       }                       
                      return (int) m_hosts.size(); 
		}
		vector < string > trun2Ip()
		{
			vector<string> vip;
			map < string, int > ::iterator iter;
			for(iter = m_hosts.begin(); iter != m_hosts.end(); iter++)
			{
				string ns = iter->first; 
				struct hostent *in = NULL;
				in = gethostbyname(ns.c_str());
				if(NULL != in)
				{
					string sip =  inet_ntoa(*(struct in_addr *) in->h_addr);
					vip.push_back(sip);
				}
				else
					cerr<<"can't translate "<<ns.c_str()<<" to ip !"<<endl;
			}
			return vip;
		}

		map < string, int > GetIPs()
		{
			map<string, int> vip;
			map < string, int > ::iterator iter;
			for(iter = m_hosts.begin(); iter != m_hosts.end(); iter++)
			{
				string ns = iter->first; 
				struct hostent *in = NULL;
				in = gethostbyname(ns.c_str());
				if(NULL != in)
				{
					string sip =  inet_ntoa(*(struct in_addr *) in->h_addr);
					vip[sip] = iter->second;
				}
				else
					cerr<<"can't translate "<<ns.c_str()<<" to ip !"<<endl;
			}
			return vip;
		}

		string toString()
		{
			ostringstream str;
			str<<"host counts = "<<m_hosts.size()<<endl;
			str<<"---------------------------------------------------"<<endl;
			map < string, int > ::iterator iter;
			for(iter = m_hosts.begin(); iter != m_hosts.end(); iter++)
				str << (iter->first).c_str() << endl;
			return str.str();
		}

};


#endif // __HOST_PARSER___H__
/*
int main(int argc , char *argv[])
{
        string s = "api[1-2].service.cn3.yahoo.com";
        if(argc < 2)
        {
           cout<<argv[0]<<" "<<s.c_str()<<endl;   
        }
       else
          s = argv[1];
        HostParser host;
        host.ParseHostString( s.c_str());
        cout<< host.toString().c_str()<<endl;
        vector <string> sip;
        sip =  host.trun2Ip();
        for(unsigned i = 0; i< sip.size(); i++)
            cout<< sip[i].c_str()<<endl;
         
	return 0;
}
*/
